﻿// <copyright file="APolicy.cs" company="Beuth Hochschule für Technik">
// Breakdown - Configure your Windows 7 Firewall
// Copyright (C) 2009 Stefan "dersteps@gmail.com" Matyba
// This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; 
// either version 3 of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program; if not, see http://www.gnu.org/licenses/.
// </copyright>
// <author>Stefan Matyba</author>
// <email>dersteps@gmail.com</email>
// <date>2009-10-18</date>
// <summary>Breakdown Application Logic - Base class for firewall policies (sets of rules)</summary>

namespace Breakdown.Logic
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using Breakdown.Aspects;
    using Ninject.Core;
    using System.Diagnostics;

    /// <summary>
    /// Defines a set of firewall rules
    /// </summary>
    [Logged]
    public class APolicy : IObserver
    {
        /// <summary>
        /// List containing all rules in this policy
        /// </summary>
        private Collection<ARule> _rules = new Collection<ARule>();

        /// <summary>
        /// The name of this policy
        /// </summary>
        private string _name;

        /// <summary>
        /// Short description of this policy
        /// </summary>
        private string _description;

        /// <summary>
        /// Determines whether or not this policy is currently active
        /// </summary>
        private bool _active;

        /// <summary>
        /// Gets the list of rules for this policy
        /// </summary>
        public Collection<ARule> Rules
        {
            get { return this._rules; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether or not this policy is active
        /// </summary>
        public bool Active
        {
            get { return this._active; }
            set { this._active = value; }
        }

        /// <summary>
        /// Gets or sets the policy's name
        /// </summary>
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }

        /// <summary>
        /// Gets or sets the policy's description
        /// </summary>
        public string Description
        {
            get { return this._description; }
            set { this._description = value; }
        }

        /// <summary>
        /// Toggles whether or not this policy is active
        /// </summary>
        public void Toggle()
        {
            this.Active = !this.Active;
        }

        /// <summary>
        /// Updates this policy when an observed Rule has been changed
        /// </summary>
        /// <param name="observed">The observed rule</param>
        public virtual void Update(IObservable observed)
        {
            // Do nothing
#if DEBUG
            Debug.WriteLine(String.Format("I have been changed: {0:S}, this is {1:S} talking!", observed.ToString(), this.ToString()));
#endif
        }

        /// <summary>
        /// Adds a firewall rule to the policy
        /// </summary>
        /// <param name="rule">The rule to add</param>
        /// <returns>Amount of rules in policy after addition</returns>
        public virtual int Add(ARule rule)
        {
            this._rules.Add(rule);
            return this._rules.Count<ARule>();
        }

        /// <summary>
        /// Removes a firewall rule from the policy
        /// </summary>
        /// <param name="rule">The rule to remove</param>
        /// <returns>Amount of rules in policy after removal</returns>
        public virtual int Remove(ARule rule)
        {
            this._rules.Remove(rule);
            return this._rules.Count<ARule>();
        }

        /// <summary>
        /// Removes all rules from the policy
        /// </summary>
        public virtual void Clear()
        {
            this._rules = new Collection<ARule>();
        }

        public virtual ARule Create()
        {
            IKernel kernel = new StandardKernel(new RuleModule());
            ARule rule = kernel.Get<FirewallRule>();
            rule.Register(this);
            return rule;
        }
    }
}
